package system

import (
	"context"
	"regexp"
	"strconv"
	"time"

	"portal/internal/common"
	"portal/internal/errorx"
	"portal/internal/svc"
	"portal/internal/tool/auth"
	"portal/internal/types"
	"portal/model"
	"portal/tools/encryption"

	"github.com/zeromicro/go-zero/core/logx"
	"github.com/zeromicro/go-zero/core/stores/sqlx"
)

type EditUserLogic struct {
	logx.Logger
	ctx       context.Context
	svcCtx    *svc.ServiceContext
	menuModel model.SysMenuModel
	userModel model.SysUserModel
}

func NewEditUserLogic(ctx context.Context, svcCtx *svc.ServiceContext) *EditUserLogic {
	return &EditUserLogic{
		Logger:    logx.WithContext(ctx),
		ctx:       ctx,
		svcCtx:    svcCtx,
		menuModel: model.NewSysMenuModel(svcCtx.Orm),
		userModel: model.NewSysUserModel(svcCtx.Orm),
	}
}

func (l *EditUserLogic) EditUser(req *types.EditUserRequest) (resp *types.CommonResponse, err error) {
	// todo: add your logic here and delete this line
	// 权限判断
	userinfo, err := auth.GetAuth(l.ctx)
	if err != nil {
		return nil, err
	}
	// 管理员仅可以控制用户账号的停用状态
	isAdmin, err := auth.IsAdmin(l.ctx)
	if err != nil {
		return nil, err
	}
	user,err := l.userModel.FindOne(l.ctx,req.UserId)
	if err != nil || user.DelFlag == "2"{
		return nil,errorx.NewBizError(500,"当前用户不存存在")
	}
	if isAdmin && userinfo.UserId != req.UserId{
		user.Status = req.Status
		err := l.userModel.Edit(l.ctx,nil,user)
		return &types.CommonResponse{
			Status: 200,
			Msg: "修改成功",
		},err
	} else {
		if userinfo.UserId != req.UserId {
			return nil,errorx.IllegalError
		}
	}
	if len(req.DeptId) != 0 {
		deptId,err := strconv.Atoi(req.DeptId)
		if err != nil {
			return nil,err
		}
		user.DeptId.Int64 = int64(deptId)
	}
	if len(req.Avatar) > 0 {
		user.Avatar = req.Avatar
	}
	if len(req.Email) > 0 {
		reg := regexp.MustCompile(common.EmailFormat)
		if !reg.MatchString(req.Email) {
			return nil, errorx.NewBizError(500, "邮箱格式不正确")
		}
		user.Email = req.Email
	}
	if len(req.Password) > 0 {
		reg := regexp.MustCompile(common.PasswordFormat)
		if !reg.MatchString(req.Password) {
			return nil,errorx.NewBizError(500,"密码格式不正确")
		}
		pwd, err := encryption.EncryptionMd5(req.Password, l.svcCtx.Config.Salt)
		if err != nil {
			return nil, err
		}
		if pwd == user.Password {
			return nil, errorx.NewBizError(500, "重置密码应与原密码不同")
		}
		user.Password = pwd
		user.PwdUpdateDate = time.Now().Unix()
	}
	if len(req.Phonenumber) > 0 {
		reg := regexp.MustCompile(common.PhoneFormat)
		if !reg.MatchString(req.Phonenumber) {
			return nil,errorx.NewBizError(500,"手机号码格式不正确")
		}
		user.Phonenumber = req.Phonenumber
	}
	if len(req.NickName) > 0 {
		user.NickName = req.NickName
	}
	user.UpdateTime = time.Now().Unix()
	user.UpdateBy = userinfo.NickName
	err = l.userModel.Edit(l.ctx,nil,user)
	if err != nil {
		return nil,err
	}
	err = oprUserRelations(l.userModel,l.ctx,req.UserId,req.PostIds,req.RoleIds,common.OPR_UPDATE)
	return &types.CommonResponse{
		Status: 200,
		Msg: "修改成功",
	},err
}

func oprUserRelations(userModel model.SysUserModel,ctx context.Context, userId int64,postIds,roleIds []*int64,opr string)error{
	isOprUR,isOprUP := false,false
	if roleIds != nil {
		isOprUR = true
	}
	if postIds != nil {
		isOprUP = true
	}

	if isOprUR {
		if opr == common.OPR_INSERT {
			err := userModel.AddUserRoles(ctx,nil,userId,roleIds)
			if err != nil {
				return err
			}
		}else if opr == common.OPR_UPDATE {
			delURs :=  make([]*int64,0)
			addURs := make([]*int64,0)
			// 修改用户对角色以及用户对岗位的映射
			urs,err := userModel.ListUserRoles(ctx,nil,userId)
			if err != nil && err != sqlx.ErrNotFound{
				return err
			}
			for _,fval := range roleIds {
				isHas := false
				for _,sval := range urs {
					if sval.RoleId == *fval {
						isHas = true
						break
					}
				}
				if !isHas {
					addURs = append(addURs, fval)
				}
			}
			for _,fval := range urs {
				isHas := false
				for _,sval := range roleIds {
					if *sval == fval.RoleId {
						isHas = true
						break
					}
				}
				if !isHas {
					delURs = append(delURs, &fval.RoleId)
				}
			}
			if len(addURs) > 0 {
				err = userModel.AddUserRoles(ctx,nil,userId,addURs)
				if err != nil {
					return err
				}
			}
			if len(delURs) > 0 {
				err = userModel.DelUserRoles(ctx,nil,userId,delURs)
				if err != nil {
					return err
				}
			}
		}
	}
	if isOprUP {
		if opr == common.OPR_INSERT {
			err := userModel.AddUserPosts(ctx,nil,userId,postIds)
			if err != nil {
				return err
			}
		}else if opr == common.OPR_UPDATE {
			delUPs :=  make([]*int64,0)
			addUPs := make([]*int64,0)
			// 修改用户对角色以及用户对岗位的映射
			ups,err := userModel.ListUserPosts(ctx,nil,userId)
			if err != nil && err != sqlx.ErrNotFound{
				return err
			}
			for _,fval := range postIds {
				isHas := false
				for _,sval := range ups {
					if sval.PostId == *fval {
						isHas = true
						break
					}
				}
				if !isHas {
					addUPs = append(addUPs, fval)
				}
			}
			for _,fval := range ups {
				isHas := false
				for _,sval := range postIds {
					if *sval == fval.PostId {
						isHas = true
						break
					}
				}
				if !isHas {
					delUPs = append(delUPs, &fval.PostId)
				}
			}
			if len(addUPs) > 0 {
				err = userModel.AddUserPosts(ctx,nil,userId,addUPs)
				if err != nil {
					return err
				}
			}
			if len(delUPs) > 0 {
				err = userModel.DelUserPosts(ctx,nil,userId,delUPs)
				if err != nil {
					return err
				}
			}
		}
	}
	return nil
}
